package cn.hznc.controller.service.toolAnalyze;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.toolAnalyze.ToolConsumptionReq;
import cn.hznc.domain.request.toolAnalyze.ToolConsumptionandUsageAnalysisReq;
import cn.hznc.domain.response.PageResult;
import cn.hznc.mapper.*;
import cn.hznc.repository.EntryExitRecordRepository;
import cn.hznc.repository.ToolForkInfoRespository;
import cn.hznc.utils.CommonUtil;
import cn.hznc.vo.ToolForkInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ToolConsumptionandUsageAnalysisService {
    @Resource
    private ToolPartMapper toolPartMapper;
    @Resource
    private EntryExitRecordMapper entryExitRecordMapper;
    @Resource
    private ToolForkInfoMapper toolForkInfoMapper;
    @Resource
    private TypeItemMapper typeItemMapper;
    @Resource
    private TypeMapper typeMapper;

    @Resource
    private EntryExitRecordRepository entryExitRecordRepository;

    @Resource
    private ToolForkInfoRespository toolForkInfoRespository;

    private static final Integer  PARENT_ID = -1;

    public PageResult<ToolConsumptionandUsageAnalysisEntity> queryToolConsumptionandUsageAnalysis(ToolConsumptionandUsageAnalysisReq toolConsumptionandUsageAnalysisReq){
        LambdaQueryWrapper<EntryExitRecordEntity> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        if (toolConsumptionandUsageAnalysisReq.getStartTime()!=null&&toolConsumptionandUsageAnalysisReq.getEndTime()!=null){
            if (toolConsumptionandUsageAnalysisReq.getStartTime().equals(toolConsumptionandUsageAnalysisReq.getEndTime())){
                Date date = toolConsumptionandUsageAnalysisReq.getEndTime();
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                calendar.add(Calendar.DATE, 1);
                date = calendar.getTime();
                toolConsumptionandUsageAnalysisReq.setEndTime(date);
            }
            lambdaQueryWrapper1.between(EntryExitRecordEntity::getCreateTime,toolConsumptionandUsageAnalysisReq.getStartTime(),toolConsumptionandUsageAnalysisReq.getEndTime());
//                lambdaQueryWrapper.gt(AbutmentOrderEntity::getReleaseTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN));
        }else {
            lambdaQueryWrapper1.between(EntryExitRecordEntity::getCreateTime, LocalDate.now().minusMonths(1),LocalDate.now());
        }
        lambdaQueryWrapper1.ne(EntryExitRecordEntity::getPartno,"");
        List<String> partno = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(toolConsumptionandUsageAnalysisReq.getIds())){
            LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper2.in(TypeEntity::getId,toolConsumptionandUsageAnalysisReq.getIds());
            List<TypeEntity> typeEntityList = typeMapper.selectList(lambdaQueryWrapper2);
            typeEntityList.forEach(typeEntity -> {
                partno.add(typeEntity.getTypeName());
                getTypeName(partno,typeEntity.getId());
            });
        }
        if (CollectionUtil.isNotEmpty(partno)){
            lambdaQueryWrapper1.in(EntryExitRecordEntity::getPartno,partno);
        }
//        if (StringUtils.isNotEmpty(toolConsumptionandUsageAnalysisReq.getQueryCondition())){
//            lambdaQueryWrapper1.like(EntryExitRecordEntity::getPartno,toolConsumptionandUsageAnalysisReq.getQueryCondition());
//        }
        List<EntryExitRecordEntity> entryExitRecordEntityList = entryExitRecordMapper.selectList(lambdaQueryWrapper1);
//        Map<String,List<EntryExitRecordEntity>> map1 = entryExitRecordEntityList.stream().collect(Collectors.groupingBy(EntryExitRecordEntity::getType));
        Map<String,List<EntryExitRecordEntity>> map = entryExitRecordEntityList.stream().collect(Collectors.groupingBy(EntryExitRecordEntity::getPartno));
        Iterator<Map.Entry<String,List<EntryExitRecordEntity>>> entries = map.entrySet().iterator();
        List<ToolConsumptionandUsageAnalysisEntity> toolConsumptionandUsageAnalysisEntityList = new ArrayList<>();
//        LambdaQueryWrapper<ToolPartEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        List<String> partno = new ArrayList<>();
//        if (CollectionUtil.isNotEmpty(toolConsumptionandUsageAnalysisReq.getIds())){
//            LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
//            lambdaQueryWrapper2.in(TypeEntity::getId,toolConsumptionandUsageAnalysisReq.getIds());
//            List<TypeEntity> typeEntityList = typeMapper.selectList(lambdaQueryWrapper2);
//            typeEntityList.forEach(typeEntity -> {
//                partno.add(typeEntity.getTypeName());
//                this.getTypeName(partno,typeEntity.getId());
//            });
//        }

//        if (CollectionUtil.isNotEmpty(partno)) {
////            toolConsumptionandUsageAnalysisReq.getPartno().forEach(s -> {
//            lambdaQueryWrapper.in(ToolPartEntity::getPartno, partno);
////            });
//        }else {
//            lambdaQueryWrapper.ne(ToolPartEntity::getPartno,"");
//        }
//        if (StringUtils.isNotEmpty(toolConsumptionandUsageAnalysisReq.getQueryCondition())){
//            lambdaQueryWrapper.like(ToolPartEntity::getPartno,toolConsumptionandUsageAnalysisReq.getQueryCondition()).or().like(ToolPartEntity::getIdnr,toolConsumptionandUsageAnalysisReq.getQueryCondition());
//        }
//        List<ToolPartEntity> toolPartEntities = toolPartMapper.selectList(lambdaQueryWrapper);
//        List<String> strings = new ArrayList<>();
//        if (CollectionUtil.isNotEmpty(toolPartEntities)){
//            toolPartEntities.forEach(toolPartEntity -> {
//                if (StringUtils.isNotEmpty(toolPartEntity.getPartno())){
//                    strings.add(toolPartEntity.getPartno());
//                }
//            });
//        }
        int flag=0;
        int startPage = (toolConsumptionandUsageAnalysisReq.getPageNo()-1)* toolConsumptionandUsageAnalysisReq.getPageSize();
        int endPage = toolConsumptionandUsageAnalysisReq.getPageNo()* toolConsumptionandUsageAnalysisReq.getPageSize();
        while (entries.hasNext()){
            Map.Entry<String,List<EntryExitRecordEntity>> entry = entries.next();
            if(flag<endPage)
            {
                flag++;
            }else {break;}
            if (flag>startPage){

                ToolConsumptionandUsageAnalysisEntity toolConsumptionandUsageAnalysisEntity = new ToolConsumptionandUsageAnalysisEntity();
//                if (strings.contains(entry.getKey())){
                    toolConsumptionandUsageAnalysisEntity.setPartno(entry.getKey());
                    LambdaQueryWrapper<ToolForkInfoEntity> lambdaQueryWrapper3 = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper3.eq(ToolForkInfoEntity::getPartno,entry.getKey());
                    lambdaQueryWrapper3.ne(ToolForkInfoEntity::getIdnr,"");
                    lambdaQueryWrapper3.ne(ToolForkInfoEntity::getType,"");
                    ToolForkInfoEntity toolPartEntities1 = toolForkInfoMapper.selectOne(lambdaQueryWrapper3);
                    if (ObjectUtil.isNotNull(toolPartEntities1)){
                        toolConsumptionandUsageAnalysisEntity.setIndr(toolPartEntities1.getIdnr());
                        toolConsumptionandUsageAnalysisEntity.setToolType(typeItemMapper.getTypeNameByType(toolPartEntities1.getType()));
                        if (ObjectUtil.isNotNull(toolPartEntities1.getPrice()))
                        toolConsumptionandUsageAnalysisEntity.setPrice(toolPartEntities1.getPrice()*entry.getValue().size());
                        toolConsumptionandUsageAnalysisEntity.setPartType(toolPartEntities1.getPartType());
                    }

                    Map<String,List<EntryExitRecordEntity>> map1 = entry.getValue().stream().collect(Collectors.groupingBy(EntryExitRecordEntity::getType));
//                    map1.get("inbound").stream().collect(Collectors.summingInt(EntryExitRecordEntity::getNumber));
                    try {
                        toolConsumptionandUsageAnalysisEntity.setInboundNum(map1.get("inbound").stream().collect(Collectors.summingInt(EntryExitRecordEntity::getNumber)));
                    }catch (Exception e){
                    }
                    try {
                        toolConsumptionandUsageAnalysisEntity.setOutboundNum(map1.get("outbound").stream().collect(Collectors.summingInt(EntryExitRecordEntity::getNumber)));
//                        if (map1.get("outbound").stream().collect(Collectors.summingInt(EntryExitRecordEntity::getNumber))>0) {
//                            List<BigDecimal> doubles = new ArrayList<>();
//                            map1.get("outbound").forEach(a -> {
//                                if (a.getPrice() != null) {
//                                    doubles.add(a.getPrice());
//                                }
//                            });
//                            if (CollectionUtil.isNotEmpty(doubles))
//                                toolConsumptionandUsageAnalysisEntity.setPrice(doubles.stream().reduce(BigDecimal.ZERO, BigDecimal::add));
//                        }
                    }catch (Exception e){
                    }
//                    LambdaQueryWrapper<ToolForkInfoEntity> lambdaQueryWrapper4 = new LambdaQueryWrapper<>();
//                    lambdaQueryWrapper4.eq(ToolForkInfoEntity::getPartno,entry.getKey());
//                    ToolForkInfoEntity toolForkInfoEntity = toolForkInfoMapper.selectOne(lambdaQueryWrapper4);
//                    if (toolForkInfoEntity != null){
//                        toolConsumptionandUsageAnalysisEntity.setPartType(toolForkInfoEntity.getPartType());
//                    }
                    toolConsumptionandUsageAnalysisEntityList.add(toolConsumptionandUsageAnalysisEntity);
//                }
            }


        }
        PageInfo<ToolConsumptionandUsageAnalysisEntity> result = new PageInfo<>(toolConsumptionandUsageAnalysisEntityList);
        return new PageResult<>(result.getList(), (long)map.size());
    }


    public PageResult<ToolConsumptionandUsageAnalysisEntity> queryToolConsumption(ToolConsumptionReq toolConsumptionReq){
        List<ToolConsumptionandUsageAnalysisEntity> resultList = new ArrayList<>();
        List<ToolConsumptionandUsageAnalysisEntity> pageList = new ArrayList<>();
        if(ObjectUtil.isNull(toolConsumptionReq.getStartTime()) || ObjectUtil.isNull(toolConsumptionReq.getEndTime())){
            Date startTime = Date.from(LocalDate.now().minusMonths(1).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
            toolConsumptionReq.setStartTime(startTime);
            toolConsumptionReq.setEndTime(new Date());
        }
        resultList = entryExitRecordRepository.selectToolConsumption(toolConsumptionReq);
        if(CollectionUtil.isNotEmpty(resultList)){
            //分页
            pageList = CommonUtil.pageList(resultList , toolConsumptionReq.getPageNum() , toolConsumptionReq.getPageSize());
            pageList.forEach(toolConsumptionandUsageAnalysisEntity -> {
                //设置出入库数量
                toolConsumptionandUsageAnalysisEntity.setInboundNum(entryExitRecordRepository.selectNumber(toolConsumptionReq.getStartTime() , toolConsumptionReq.getEndTime() , "" , toolConsumptionandUsageAnalysisEntity.getPartno() , "" , "inbound"));
                toolConsumptionandUsageAnalysisEntity.setOutboundNum(entryExitRecordRepository.selectNumber(toolConsumptionReq.getStartTime() , toolConsumptionReq.getEndTime() , "" , toolConsumptionandUsageAnalysisEntity.getPartno() , "" , "outbound"));
                //设置基础信息字段
                ToolForkInfoVo toolForkInfoVo = toolForkInfoRespository.selectResult(toolConsumptionandUsageAnalysisEntity.getPartno());
                toolConsumptionandUsageAnalysisEntity.setToolType(toolForkInfoVo.getToolType());
                toolConsumptionandUsageAnalysisEntity.setPrice(toolForkInfoVo.getPrice());
                toolConsumptionandUsageAnalysisEntity.setPartType(toolForkInfoVo.getPartType());
                toolConsumptionandUsageAnalysisEntity.setIndr(toolForkInfoVo.getIndr());
            });
        }
        return new PageResult<>(pageList, (long)resultList.size());
    }


    public List<TypeEntity> queryAllType(){
//        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        List<TypeEntity> typeEntities = typeMapper.selectList(lambdaQueryWrapper);
//        List<TypeEntity> tree = new ArrayList<>();
//        List<TypeEntity> parentTypeEntity = typeEntities.stream().filter(dept -> dept.getParentId().equals(0)).collect(Collectors.toList());
        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TypeEntity::getParentId , PARENT_ID);
        List<TypeEntity> tree = new ArrayList<>();
        TypeEntity typeEntity = typeMapper.selectOne(lambdaQueryWrapper);
        if(ObjectUtil.isNull(typeEntity)){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<TypeEntity> wrapper = new LambdaQueryWrapper<>();
        List<TypeEntity> typeEntities = typeMapper.selectList(wrapper);
        List<TypeEntity> parentTypeEntity = typeEntities.stream().filter(dept -> dept.getParentId().equals(PARENT_ID)).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(parentTypeEntity)){
            parentTypeEntity.forEach(parentTypeEntity1 -> {
                tree.add(parentTypeEntity1);
                addChild(parentTypeEntity1, typeEntities);
            });
        }
        return tree;

    }

    private void addChild(TypeEntity parentTypeEntity, List<TypeEntity> all) {
        List<TypeEntity> tempList = all.stream()
                .filter(dept -> parentTypeEntity.getId().equals(dept.getParentId()))
                .collect(Collectors.toList());
        Map map = new HashMap();
        map.put("title","custom");
        parentTypeEntity.setScopedSlots(map);
        parentTypeEntity.setChildren(tempList);
        tempList.forEach(dept -> {
            addChild(dept, all);
        });
    }


//    public List<TypeEntity> queryAllType(){
////        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
////        List<TypeEntity> typeEntities = typeMapper.selectList(lambdaQueryWrapper);
////        List<TypeEntity> tree = new ArrayList<>();
////        List<TypeEntity> parentTypeEntity = typeEntities.stream().filter(dept -> dept.getParentId().equals(0)).collect(Collectors.toList());
//        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(TypeEntity::getParentId , PARENT_ID);
//        List<TypeEntity> tree = new ArrayList<>();
//        List<TypeEntity> parentTypeEntity = new ArrayList<>();
//        TypeEntity typeEntity = typeMapper.selectOne(lambdaQueryWrapper);
//        if(ObjectUtil.isNull(typeEntity)){
//            return new ArrayList<>();
//        }
//        LambdaQueryWrapper<TypeEntity> wrapper = new LambdaQueryWrapper<>();
//        List<TypeEntity> typeEntities = typeMapper.selectList(wrapper);
//        parentTypeEntity = typeEntities.stream().filter(dept -> dept.getParentId().equals(typeEntity.getId())).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(parentTypeEntity)){
//            parentTypeEntity.forEach(parentTypeEntity1 -> {
//                tree.add(parentTypeEntity1);
//                addChild(parentTypeEntity1, typeEntities);
//            });
//        }
//        return tree;
//
//    }

    public List<TypeEntity> findChild(List<TypeEntity> list , Integer fatherId){

        List<TypeEntity> list2 = new ArrayList<>();

        if(fatherId != null ){
            List <TypeEntity> ByFatherList = list.stream().filter(item-> fatherId == item.getParentId()).collect(Collectors.toList());

            List<TypeEntity>  ByOtherList = list.stream().filter(item->fatherId != item.getParentId()).collect(Collectors.toList());

            for (TypeEntity typeEntity:ByFatherList) {
                if(typeEntity.getParentId() == fatherId){
                    typeEntity.setChildren(findChild(ByOtherList, typeEntity.getId()));
                    list2.add(typeEntity);
                }
            }
        }
        return  list2;
    }

    public Boolean deleteTypeById(Integer id){
        List<Integer> ids = new ArrayList<>();
        ids.add(id);
        this.getIds(ids,id);
        ids.forEach(integer -> {
            typeMapper.deleteById(integer);
        });
        return Boolean.TRUE;
    }
    private void getIds(List<Integer> ids, Integer parentId) {
        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TypeEntity::getParentId,parentId);
        List<TypeEntity> contents = typeMapper.selectList(lambdaQueryWrapper);
        for (TypeEntity content : contents) {
            Integer id = content.getId();
            ids.add(id);
            this.getIds(ids,id);
        }
    }
    public void getTypeName(List<String> partno, Integer parentId) {
        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TypeEntity::getParentId,parentId);
        List<TypeEntity> contents = typeMapper.selectList(lambdaQueryWrapper);
        for (TypeEntity content : contents) {
            String typeName = content.getTypeName();
            Integer id = content.getId();
            partno.add(typeName);
            this.getTypeName(partno,id);
        }
    }
    public Boolean insertType(Integer id,String typeName) throws Exception{
        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TypeEntity::getParentId,id);
        lambdaQueryWrapper.eq(TypeEntity::getTypeName,typeName);

        if (typeMapper.selectOne(lambdaQueryWrapper) != null){
            throw new Exception("该类型已存在");
        }
        TypeEntity typeEntity = new TypeEntity();
        typeEntity.setTypeName(typeName);
        typeEntity.setParentId(id);
        typeMapper.insert(typeEntity);
        return Boolean.TRUE;
    }
    public Boolean updateType(Integer id,String typeName) throws Exception{
        TypeEntity typeEntity = typeMapper.selectById(id);

        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TypeEntity::getParentId,typeEntity.getParentId());
        lambdaQueryWrapper.eq(TypeEntity::getTypeName,typeName);
        if (typeMapper.selectOne(lambdaQueryWrapper) != null){
            throw new Exception("该类型已存在");
        }
        typeEntity.setTypeName(typeName);
        typeMapper.updateById(typeEntity);
        return Boolean.TRUE;
    }


}
